#include "strategies/PessimisticDrawingStrategy.h"
#include "CCardStack.h"
#include "Query.h"

using namespace Card;

bool PessimisticDrawingStrategy::pickFromDiscard(CCardStack* hand, const GameState* gameState) {
    bool decision;
    const CCard& topOfDiscard = gameState->getCardsInDiscard().back();
    int discardValue = calculateGain(hand, CCard(topOfDiscard.GetIndex()), true, gameState);
    if (discardValue > 0) {
        float deckValue = 0;
        float probability;
        CCardStack possibleCards = gameState->getUnknownCards(gameState->getCurrPlayer());
        if (possibleCards.Size() > 0) {
            for (int suit = Spades; suit <= Diamonds; suit++) {
                CCardStack minCards = Query::minValueCards(possibleCards, (eSuit) suit);
                float suitValue = calculateGain(hand, minCards.at(0), false, gameState);
                float suitProbability = (float) minCards.Size() / possibleCards.Size();
                if (suitValue > deckValue) {
                    deckValue = suitValue;
                    probability = suitProbability;
                }
            }
            decision = (discardValue >= deckValue) ? true : false;
            if (decision) {
                decisionCertainty = (int) (100 * probability);
                // The discard card is better if the agent is right;
            }
            else {
                decisionCertainty = 100;
                // The known card is worse than the worst unknown card --> 100% certainty
            }
        }
        else {
            decision = false;
            decisionCertainty = 100;
        }
    }
    else {
        decision = false;
        decisionCertainty = 100;
    }
    return decision;
}

int PessimisticDrawingStrategy::calculateGain(CCardStack* hand, const CCard& card, bool picked, const GameState* gameState) {
    int ret = 0;
    if (discardStrategy != NULL) {
        hand->Push(card);
        int discardDecision = discardStrategy->pickDiscard(hand, picked, gameState);
        hand->Pop();
        ret = Query::gainFromCard(*hand, card, discardDecision);
    }
    else {
        Query::debugOut(string("Discard strategy not set for ODS"), 1);
    }
    return ret;
}
